package util

import (
	"fmt"
	"strconv"
	"strings"
)

//ProcessStickPackage 处理粘包
func ProcessStickPackage(startFlag byte, endFlag byte, allBytes *[]byte) [][]byte {
	if allBytes == nil {
		return nil
	}
	startFound := false
	startIndex := 0
	endIndex := 0
	result := make([][]byte, 0)
	for i, curByte := range *allBytes {
		//如果还未匹配到开头，且当前字节等于开始标记
		if !startFound && curByte == startFlag {
			startFound = true
			startIndex = i
			continue
		}
		//如果已经匹配到开始标记，且当前数据是结束标记
		if startFound && curByte == endFlag {
			endIndex = i
			startFound = false //匹配一次完整数据后，重新开始
			tmp := (*allBytes)[startIndex : endIndex+1]
			result = append(result, tmp)
		}
	}
	if endIndex != 0 {
		*allBytes = (*allBytes)[endIndex+1:]
	}
	return result
}

//处理转义后的数据
func ReverseEscapeBytes(datas []byte, flag1, flag2, byte1, byte2 byte) []byte {
	if datas == nil {
		return nil
	}
	dataLen := len(datas)

	result := make([]byte, 0, dataLen)

	for i := 0; i < dataLen; i++ {
		curByte := datas[i]
		if i == dataLen-1 {
			result = append(result, curByte)
			break
		}

		nextByte := datas[i+1]
		if curByte == flag2 && nextByte == byte1 {
			result = append(result, flag1)
			i++
			continue
		}

		if curByte == flag2 && nextByte == byte2 {
			result = append(result, flag2)
			i++
			continue
		}

		result = append(result, curByte)
	}
	return result
}

//对数据进行转义
func EscapeBytes(datas []byte, flag1, flag2, byte1, byte2 byte) []byte {
	if datas == nil {
		return nil
	}
	retBytes := make([]byte, 0, len(datas))
	for _, v := range datas {
		if v == flag1 {
			retBytes = append(retBytes, flag2, byte1)
		} else if v == flag2 {
			retBytes = append(retBytes, flag2, byte2)
		} else {
			retBytes = append(retBytes, v)
		}
	}
	return retBytes
}

//GetXOR获取指定开始索引到结束索引之前的数据的异或值
func GetXOR(datas []byte, startIndex int, endIndex int) byte {
	if datas == nil || startIndex > endIndex {
		return 0
	}
	xorResult := datas[startIndex]
	for i := startIndex + 1; i <= endIndex; i++ {
		xorResult = xorResult ^ datas[i]
	}
	return xorResult
}

func BCD2Str(bcdBytes []byte) string {
	result := ""
	for i := 0; i < len(bcdBytes); i++ {
		tmp := bcdBytes[i]
		result = result + strconv.Itoa(int(tmp>>4))
		result = result + strconv.Itoa(int((tmp<<4)>>4))
	}
	return result
}

func Str2BCD(bcdStr string) []byte {
	//内容长度无法被2整除时，前补"0"
	if len(bcdStr)%2 != 0 {
		bcdStr = "0" + bcdStr
	}
	result := make([]byte, len(bcdStr)/2)
	for i := 0; i < len(result); i++ {
		tmp := i * 2
		r, _ := strconv.ParseUint(bcdStr[tmp:tmp+2], 16, 8)
		result[i] = byte(r)
	}
	return result
}

func Bytes2HexString(bytes []byte) string {
	var sa = make([]string, 0)
	for _, v := range bytes {
		sa = append(sa, fmt.Sprintf("%02X", v))
	}
	ss := strings.Join(sa, "-")
	return ss
}
